package asset;

public class RegFile {
    
    private static int[] reg = new int[32];
    private static int hi = 0;
    private static int lo = 0;
    private static int c0 = 0;
    private static boolean outputEnable = true;

    public static void outConfig(boolean ifoutput) {
        outputEnable = ifoutput;
    }

    // Note:保留，初始化mars中非0初始值的寄存器
    public static void marsInitial() {
    }

    public static void write(String addrString, int data) throws Exception {
        if (addrString.equals("hi")) {
            hi = data;
            PC.next();
            return;
        }
        else if (addrString.equals("lo")) {
            lo = data;
            PC.next();
            return;
        }
        else if (addrString.equals("c0")) {
            c0 = data;
            PC.next();
            return;
        }

        int addr = Define.getRegIndex(addrString);
        if (addr > 0 && 32 > addr) {
            reg[addr] = data;
            if (outputEnable) {
                System.out.print(String.format("@%08x: $%-2d <= %08x",PC.getValue(),addr,data));
            }
        }
        else if (addr != 0) {
            throw new Exception("reg file Waddr " + addrString + " is out of 0-31");
        }
        PC.next();
    }

    public static void write(Object... objects) throws Exception {
        if ((objects.length & 1) != 0) {
            write((String)objects[0],(int)objects[1]);
        }
        String addrString;
        int data;
        for (int i = 0; i < objects.length; i += 2) {
            addrString = (String)objects[i];
            data = (int)objects[i + 1];
            if (addrString.equals("hi")) {
                hi = data;
                continue;
            }
            else if (addrString.equals("lo")) {
                lo = data;
                continue;
            }
            else if (addrString.equals("c0")) {
                c0 = data;
                continue;

            }

            int addr = Define.getRegIndex(addrString);
            if (addr > 0 && 32 > addr) {
                reg[addr] = data;
                if (outputEnable) {
                    System.out.print(String.format("@%08x: $%-2d <= %08x",PC.getValue(),addr,data));
                }
            }
            else if (addr != 0) {
                throw new Exception("reg file Waddr " + addrString + " is out of 0-31");
            }
        }
        PC.next();
    }

    public static int read(String addrString) throws Exception {
        if (addrString.equals("hi")) {
            return hi;
        }
        else if (addrString.equals("lo")) {
            return lo;
        }
        else if (addrString.equals("c0")) {
            return c0;
        }

        int addr = Define.getRegIndex(addrString);
        if (addr >= 0 && 32 > addr) {
            return reg[addr];
        }
        else {
            throw new Exception("reg file Waddr " + addrString + " is out of 0-31");
        }
    }
}
